from typing import List, Optional, Dict, Any
from datetime import datetime
import uuid
import json
import re
from app.database.database import get_db_with_dict_factory
from app.models.prompt_template import PromptTemplateCreate, PromptTemplateUpdate, TemplateVariable

class PromptTemplateService:
    def __init__(self):
        self.db = get_db_with_dict_factory()

    async def get_all_templates(self, category: Optional[str] = None, tag: Optional[str] = None):
        """获取所有提示词模板，可按分类或标签筛选"""
        cursor = self.db.cursor()
        print("获取所有提示词模板")
        query = "SELECT * FROM prompt_templates"
        params = []
        
        if category:
            query += " WHERE category = ?"
            params.append(category)
        
        if tag:
            if category:
                query += " AND"
            else:
                query += " WHERE"
            query += " tags LIKE ?"
            params.append(f'%"{tag}"%')
        
        query += " ORDER BY name"
        
        cursor.execute(query, params)
        templates = cursor.fetchall()
        
        # 处理 JSON 字段
        for template in templates:
            if template['variables']:
                template['variables'] = json.loads(template['variables'])
            else:
                template['variables'] = []
                
            if template['tags']:
                template['tags'] = json.loads(template['tags'])
            else:
                template['tags'] = []
        
        return templates

    async def get_template_by_id(self, template_id: str):
        """根据 ID 获取提示词模板"""
        cursor = self.db.cursor()
        cursor.execute("SELECT * FROM prompt_templates WHERE id = ?", (template_id,))
        template = cursor.fetchone()
        
        if template:
            # 处理 JSON 字段
            if template['variables']:
                template['variables'] = json.loads(template['variables'])
            else:
                template['variables'] = []
                
            if template['tags']:
                template['tags'] = json.loads(template['tags'])
            else:
                template['tags'] = []
        
        return template

    async def create_template(self, template_data: PromptTemplateCreate):
        """创建新的提示词模板"""
        cursor = self.db.cursor()
        
        template_id = str(uuid.uuid4())
        now = datetime.now().isoformat()
        
        # 将变量和标签转换为 JSON 字符串
        variables_json = json.dumps(template_data.variables, default=lambda x: x.dict())
        tags_json = json.dumps(template_data.tags)
        
        cursor.execute(
            """
            INSERT INTO prompt_templates (
                id, name, description, system_prompt, user_prompt,
                variables, category, tags, created_at, updated_at
            ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
            """,
            (
                template_id, template_data.name, template_data.description,
                template_data.system_prompt, template_data.user_prompt,
                variables_json, template_data.category, tags_json,
                now, now
            )
        )
        
        self.db.commit()
        
        return await self.get_template_by_id(template_id)

    async def update_template(self, template_id: str, template_data: PromptTemplateUpdate):
        """更新提示词模板"""
        cursor = self.db.cursor()
        
        # 检查模板是否存在
        cursor.execute("SELECT * FROM prompt_templates WHERE id = ?", (template_id,))
        existing = cursor.fetchone()
        
        if not existing:
            return None
            
        now = datetime.now().isoformat()
        
        # 准备更新数据
        update_data = {}
        if template_data.name is not None:
            update_data['name'] = template_data.name
        if template_data.description is not None:
            update_data['description'] = template_data.description
        if template_data.system_prompt is not None:
            update_data['system_prompt'] = template_data.system_prompt
        if template_data.user_prompt is not None:
            update_data['user_prompt'] = template_data.user_prompt
        if template_data.variables is not None:
            update_data['variables'] = json.dumps(template_data.variables, default=lambda x: x.dict())
        if template_data.category is not None:
            update_data['category'] = template_data.category
        if template_data.tags is not None:
            update_data['tags'] = json.dumps(template_data.tags)
        
        update_data['updated_at'] = now
        
        # 构建 SQL 更新语句
        fields = ', '.join([f"{key} = ?" for key in update_data.keys()])
        values = list(update_data.values())
        values.append(template_id)
        
        cursor.execute(
            f"UPDATE prompt_templates SET {fields} WHERE id = ?",
            values
        )
        
        self.db.commit()
        
        return await self.get_template_by_id(template_id)

    async def delete_template(self, template_id: str):
        """删除提示词模板"""
        cursor = self.db.cursor()
        
        # 检查模板是否存在
        cursor.execute("SELECT * FROM prompt_templates WHERE id = ?", (template_id,))
        existing = cursor.fetchone()
        
        if not existing:
            return False
            
        # 删除模板
        cursor.execute("DELETE FROM prompt_templates WHERE id = ?", (template_id,))
        self.db.commit()
        
        return True

    async def process_template(self, template_id: str, variables: dict):
        """处理提示词模板，替换变量"""
        print(f"Processing template with ID: {template_id}")
        print(f"Variables type: {type(variables)}")
        print(f"Variables content: {variables}")
        
        template = await self.get_template_by_id(template_id)
        if not template:
            print(f"Template not found: {template_id}")
            raise ValueError(f"找不到ID为 {template_id} 的模板")
        
        print(f"Template found: {template}")
        
        system_prompt = template["system_prompt"]
        user_prompt = template["user_prompt"]
        
        print(f"Template variables: {template['variables']}")
        
        # 处理系统提示词中的变量
        if system_prompt:
            for var in template["variables"]:
                var_name = var["name"]
                placeholder = f"{{{var_name}}}"
                
                print(f"Processing variable: {var_name}")
                
                # 如果变量值在传入的变量字典中
                if var_name in variables and variables[var_name]:
                    print(f"Variable {var_name} found in variables with value: {variables[var_name]}")
                    system_prompt = system_prompt.replace(placeholder, str(variables[var_name]))
                # 否则使用默认值
                elif "default_value" in var and var["default_value"]:
                    print(f"Using default value for {var_name}: {var['default_value']}")
                    system_prompt = system_prompt.replace(placeholder, var["default_value"])
                # 如果是特殊变量，使用特殊处理
                elif var_name.startswith("_"):
                    print(f"Processing special variable: {var_name}")
                    # 这里处理特殊变量，如 _title, _references, _sample 等
                    system_prompt = self._process_special_variable(system_prompt, var_name, placeholder, variables)
                else:
                    # 如果没有值也没有默认值，保留占位符
                    print(f"No value or default value for {var_name}, keeping placeholder")
                    pass
        
        # 处理用户提示词中的变量
        if user_prompt:
            for var in template["variables"]:
                var_name = var["name"]
                placeholder = f"{{{var_name}}}"
                
                # 如果变量值在传入的变量字典中
                if var_name in variables and variables[var_name]:
                    user_prompt = user_prompt.replace(placeholder, variables[var_name])
                # 否则使用默认值
                elif "default_value" in var and var["default_value"]:
                    user_prompt = user_prompt.replace(placeholder, var["default_value"])
                # 如果是特殊变量，使用特殊处理
                elif var_name.startswith("_"):
                    # 这里处理特殊变量，如 _title, _references, _sample 等
                    user_prompt = self._process_special_variable(user_prompt, var_name, placeholder, variables)
                else:
                    # 如果没有值也没有默认值，保留占位符
                    pass
        
        result = {
            "system_prompt": system_prompt,
            "user_prompt": user_prompt
        }
        
        print(f"Processed result: {result}")
        
        return result
    
    def _process_special_variable(self, prompt, var_name, placeholder, variables):
        """处理特殊变量，只有在用户提供了相应内容时才替换"""
        # 文章标题
        if var_name == "_title" and "_title" in variables and variables["_title"]:
            return prompt.replace(placeholder, variables["_title"])
        
        # 参考内容
        elif var_name == "_references" and "_references" in variables:
            references = variables["_references"]
            if isinstance(references, list) and references:
                refs_text = "参考资料：\n\n"
                for i, ref in enumerate(references):
                    if isinstance(ref, dict) and "title" in ref and "content" in ref:
                        # 限制每个参考内容的长度
                        content = ref["content"]
                        if len(content) > 1500:
                            content = content[:1500] + "..."
                        refs_text += f"参考 {i+1}：{ref['title']}\n{content}\n\n"
                return prompt.replace(placeholder, refs_text)
            # 如果没有有效的参考内容，返回空字符串替换占位符
            return prompt.replace(placeholder, "")
        
        # 用户样本
        elif var_name == "_sample" and "_sample" in variables and variables["_sample"]:
            sample = variables["_sample"]
            return prompt.replace(placeholder, f"参考样本：\n\n{sample}")
        
        # 如果没有提供相应内容或不是已知的特殊变量，返回空字符串替换占位符
        return prompt.replace(placeholder, "")

    def __del__(self):
        """确保数据库连接被正确关闭"""
        if hasattr(self, 'db'):
            self.db.close() 